<template>
  <!-- 表单组件核心代码 -->
  <el-form class="custom_form" :ref="formRef" :model="formModel" label-position="right" v-bind="$attrs" :rules="formRules">
    <el-row :gutter="15">
      <el-col v-for="(item, index) in formItemConfig" v-show="!item.hidden" :key="index" :span="item.span">
        <div class="custom_form_item">
          <p v-if="item.title" class="cf_title">{{ item.title }}</p>
          <el-form-item v-else style="width: 100%" :label="item.label" :label-width="item.labelWidth" :prop="item.prop" size="small">
            <template v-if="item.slotName">
              <slot :name="item.slotName" :scope="item"></slot>
            </template>
            <component :class="item.class" v-else-if="componentNames.findIndex(name => name === item.component) > -1" v-model="formModel[item.prop]" controls-position="right" v-bind="item" :is="isComponentName(item)" :placeholder="placeholder(item)" :style="style(item)" @input="changeValue(item, $event)" @click="handleClick(item, $event)" @change="handleChange(item, $event)" />
            <component :class="item.class" v-else-if="item.component == 'el-input-number' && (item.max !== undefined || item.min !== undefined)" v-model="formModel[item.prop]" controls-position="right" v-bind="item" :is="isComponentName(item)" :placeholder="placeholder(item)" :style="style(item)" @input="changeValue(item, $event)" @change="handleChange(item, $event)" />
            <component :class="item.class" v-else v-model="formModel[item.prop]" controls-position="right" v-bind="item" :is="isComponentName(item)" :placeholder="placeholder(item)" :style="style(item)" @input="changeValue(item, $event)" @change="handleChange(item, $event)" />
          </el-form-item>
        </div>
      </el-col>
    </el-row>
  </el-form>
</template>

<script>
/**
 * @desc 表单组件
 * @param {Object} formRef - el-form 的 ref 名称
 * @param {Object} formItemModel - 表单数据模型
 * @param {Object} formConfig - el-form-item 配置项
 * @param {Object} formRules - el-form-item 验证规则
 */
export default {
  props: {
    // 表单引用名称
    formRef: {
      type: String,
      default: 'formRef',
    },
    // 表单数据模型
    formModel: {
      type: Object,
      default: () => ({}),
    },
    // 表单项配置
    formItemConfig: {
      type: Array,
      default: () => [],
    },
    // 表单验证规则
    formRules: {
      type: Object,
      default: () => ({}),
    },
  },
  data () {
    return {
      componentNames: ['el-select', 'radio', 'checkbox', 'DateTimePicker'],
    };
  },
  created () {
  },
  computed: {
    style () {
      return item => {
        if (item.style) {
          return typeof item.style == 'string' ? { width: item.width } : item.style;
        } else {
          if (item.width) {
            return { width: item.width };
          } else {
            return { width: '100%' };
          }
        }
      };
    },
    /**
     * 根据组件类型获取需要渲染的组件名称
     */
    isComponentName () {
      let comp = this.componentNames;
      return item => {
        if (item.component === comp[0]) {
          return 'SelectForm';
        } else if (item.component === comp[1]) {
          return 'RadioGroupForm';
        } else if (item.component === comp[2]) {
          return 'CheckboxGroupForm';
        } else if (item.component === comp[3]) {
          return 'BaseDateTimePicker';
        } else {
          return item.component || 'el-input';
        }
      };
    },
    /**
     * 根据表单项配置获取占位符
     */
    placeholder () {
      return item => {
        if (item.placeholder) return item.placeholder;
        const arr = ['el-input', 'el-input-number'];
        return !item.component || arr.includes(item.component) ? `请输入${item.label || ''}` : `请选择${item.label || ''}`;
      };
    },
  },
  methods: {
    /**
     * 验证表单并执行回调函数
     * @param {Function} cb - 表单验证通过后的回调函数
     * @returns {boolean} - 表单验证结果
     */
    validate (valida) {
      this.$refs[this.formRef].validate(valid => {
        valida(valid, this.formModel);
        if (valid) {
          // 通过
        } else {
          // 失败
          return false;
        }
      });
    },
    /**
     * 表格重置
     */
    toResetFields(){
      this.$refs[this.formRef].resetFields();
    },
    /**
     * 处理表单项的点击事件
     * @param {Object} item - 当前点击的表单项配置
     */
    handleClick (item, e) {
      // 处理数据改变的逻辑
      item.onClick ? item.onClick(e, item) : () => { };
    },
    //change型式的回调
    handleChange (item, e) {
      item.onChange ? item.onChange(e, item) : () => { };
    },
    /**
     * 更新表单数据模型到父组件
     */
    changeValue (item, e) {
      this.$emit('input', e);
    },
  },
};
</script>
<style lang="less">
@import url("@/common/elementui");
.custom_form {
  .custom_form_item {
    .cf_title {
      line-height: 30px;
      text-align: left;
      position: relative;
      &::before {
        content: "";
        position: absolute;
        left: -5px;
        width: 5px;
        height: 100%;
        background-color: #ffa13f;
      }
    }
  }
}
</style>
